package groovy4u;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class Shell {

	private static Log logger = LogFactory.getLog(Shell.class);
	
	public static void main(String[] args) {

		if (args.length == 0) {
			throw new RuntimeException("Class name is needed!");
		}

		//initialize command
		try {
			Class<?> clazz = Class.forName(args[0]);
			Command command = (Command)clazz.newInstance();
			
			if (args.length > 1) {
				logger.info("set command parameters:");
				for (int i = 1; i < args.length; i ++) {
					Object[] params = parseParameters(args[i]);
					if (params != null && params.length > 0) {
						String fieldName = (String)params[0];
						Object fieldValue = params[1];
						logger.info(fieldName + " \t= " + fieldValue);
						try {
							Field field = clazz.getField(fieldName);
							field.set(command, fieldValue);
						} catch (Exception e) {
							String methondName = "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
							Method method;
							try {
								method = clazz.getMethod(methondName, Object.class);
								method.invoke(command, new Object[] { fieldValue });
							} catch (Exception ex) {
								logger.error(e);
							}
						}
					}
				}
			}
			//run command
			try {
				logger.info("execute command ...");
				long start = System.currentTimeMillis();
				command.before();
				command.execute();
				command.after();
				logger.info("complete: " + (System.currentTimeMillis() - start) + " ms");
			} catch (Exception e) {
				command.usage(e.getClass().getName() + ": " + e.getMessage());
				logger.error(e);
			}
		} catch (Exception e) {
			logger.error(e);
		}
	}
	
	private static Object[] parseParameters(String arg) {

		Object[] params = null;
		if (arg == null || arg.trim().length() == 0 || !arg.startsWith("/")) {
		} else if (arg.indexOf(":") == -1) {
			Pattern pattern = Pattern.compile("\\/([^:]*)");
			Matcher m = pattern.matcher(arg);
			
			if (m.find()) {
				params = new Object[] {m.group(1), true};
			}
		} else {
			Pattern pattern = Pattern.compile("\\/([^:]*):(.*)");
			Matcher m = pattern.matcher(arg);
			if (m.find()) {
				params = new Object[] {m.group(1), m.group(2)};
			}
		}
		return params;
	}
}
